package client;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;


import saxion.sensor.structuur.DataStruc;
import saxion.sensor.structuur.Sensor;

public class SensorCreator {

		private String sensorXML = "sensorGen.xml";
		private String sensorDataXML = "DataGen.xml";
	
	   public Sensor createRandomSensor(int id, int fields)
	   {
		   Sensor sensor = new Sensor();
		   sensor.setName("TestSensor" + id);
		   sensor.setDescription("Dit is een test sensor"+ id);
		   
		   ArrayList<DataStruc> sensorDataStruc = new  ArrayList<DataStruc>();
			
		   Random randType = new Random(); 
		   
		   for(int i=1; i < fields; i++){
			   DataStruc dataStruc = new DataStruc();
			   dataStruc.setName("Field"+i);
			   
			   switch(randType.nextInt(2)){
				   case 0:
					   dataStruc.setType("Int");
					   break;
				   case 1:
					   dataStruc.setType("String");
					   break;
				   case 2:
					   dataStruc.setType("bool");
					   break;
			   }

			   
			   sensorDataStruc.add(dataStruc);
		   }

		   sensor.setDatastructuur(sensorDataStruc);

		   
		   return sensor;
		  

	   }
	   
	   public byte[] convertSensorToXML(Sensor sensor)
	   {
		   	createSensorXML(sensor);
		   
		   	Path path = Paths.get(sensorXML);
	        byte[] data = null;
	        
			try {
				data = Files.readAllBytes(path);
			} catch (IOException e) {
				e.printStackTrace();
			}
		
			return data;
	   }
	   

		public  byte[] generateRandomDataForSensor(Sensor sensor) throws Exception
		   {

			  List<DataStruc> sensorFields  = sensor.getDatastructuur();
			  ArrayList<SensorData> sensorData = new  ArrayList<SensorData>();
			   
			  for(int i=0; i < sensorFields.size(); i++)
			  {
				  String value = null;
				  
				  switch(sensorFields.get(i).getType())
				  {
				  case "Int":
					  value = "1";
					  break;
				  case "String":
					  value = "Test tekst";
					  break;
				  case "bool":
					  value = "true";
				  	  break;
					  
				  }

				  sensorData.add(new SensorData(sensorFields.get(i).getName(), value));
			  }

			   createDataXML(Integer.toString(sensor.getId()) , sensorData);
		        
			   //send test data
			   Path path = Paths.get(sensorDataXML);
		        byte[] data = null;
		        
				try {
					data = Files.readAllBytes(path);
				} catch (IOException e) {
					e.printStackTrace();
				}
		      
				return data;
				
		   }
		
		  public void createDataXML(String sensorId, ArrayList<SensorData> values)
		   { 
			   try{
			   
				DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
				DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
		 
				// root elements
				Document doc = docBuilder.newDocument();
				Element rootElement = doc.createElement("sensordata");
				doc.appendChild(rootElement);
				
				// id elements
				Element id = doc.createElement("id");
				id.appendChild(doc.createTextNode(sensorId));
				rootElement.appendChild(id);
				
				// data elements
				Element data = doc.createElement("data");
				rootElement.appendChild(data);
			
				
				for(SensorData value : values)
				{
					Element field = doc.createElement(value.fieldName);
					field.appendChild(doc.createTextNode(value.value));
					data.appendChild(field);
				}
							
				
				TransformerFactory transformerFactory = TransformerFactory.newInstance();
				Transformer transformer = transformerFactory.newTransformer();
				DOMSource source = new DOMSource(doc);
				StreamResult result = new StreamResult(new File(sensorDataXML));
		 
				// Output to console for testing
				// StreamResult result = new StreamResult(System.out);
		 
				transformer.transform(source, result);
		 
				System.out.println("File saved!");
				
			   }
			   catch(Exception e)
			   {
				   e.printStackTrace();
			   }
			   
		   }
	   
	   private void createSensorXML(Sensor sensor)
	   { 
		   try{
		   
			DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
	 
			// root elements
			Document doc = docBuilder.newDocument();
			Element rootElement = doc.createElement("sensor");
			doc.appendChild(rootElement);
			
			Element nameEl = doc.createElement("name");
			nameEl.appendChild(doc.createTextNode(sensor.getName()));
			rootElement.appendChild(nameEl);
			
			Element descEL = doc.createElement("description");
			descEL.appendChild(doc.createTextNode(sensor.getDescription()));
			rootElement.appendChild(descEL);
			
			
			for(DataStruc dataStruc : sensor.getDatastructuur())
			{
				// data elements
				Element data = doc.createElement("datastruc");
				rootElement.appendChild(data);
				
				Element field = doc.createElement("name");
				field.appendChild(doc.createTextNode(dataStruc.getName()));
				data.appendChild(field);
				
				Element field2 = doc.createElement("type");
				field2.appendChild(doc.createTextNode(dataStruc.getType()));
				data.appendChild(field2);
			}
						
			
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(doc);
			StreamResult result = new StreamResult(new File(sensorXML));

			transformer.transform(source, result);
			
		   }
		   catch(Exception e)
		   {
			   e.printStackTrace();
		   }
		   
	   }
	   
	   
	 class SensorData{
            
            public SensorData(String fieldname, String value)
            {
                    this.fieldName = fieldname;
                    this.value = value;
            }
            
            public String fieldName;
            public String value;
    
    }
    
    class SensorDataType{
            
            public SensorDataType(String fieldname, String type)
            {
                    this.fieldName = fieldname;
                    this.type = type;
            }
            
            public String fieldName;
            public String type;
    
    }
}
